package com.xk857.article.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xk857.article.mapper.ArticleMapper;
import com.xk857.article.req.ArticleListREQ;
import com.xk857.article.req.ArticleREQ;
import com.xk857.article.req.ArticleUserREQ;
import com.xk857.article.service.IArticleService;
import com.xk857.entities.Article;
import com.xk857.feign.req.UserInfoREQ;
import com.xk857.util.base.Result;
import com.xk857.util.enums.ArticleStatusEnum;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 文章信息表 服务实现类
 *
 * @author CV大魔王
 * @since 2021-02-21
 */
@Service
public class ArticleServiceImpl extends ServiceImpl<ArticleMapper, Article> implements IArticleService {

    @Override
    public IPage<Article> queryPage(ArticleREQ req) {
        QueryWrapper<Article> wrapper = new QueryWrapper<>();
        if (req.getStatus() != null) {
            wrapper.eq("status", req.getStatus());
        }
        if (StringUtils.isNotEmpty(req.getTitle())) {
            wrapper.like("title", req.getTitle());
        }
        // 排序
        wrapper.orderByDesc("update_date");

        return baseMapper.selectPage(req.getPage(), wrapper);
    }


    @Override
    public Article findArticleAndLabelById(String id) {
        return baseMapper.findArticleAndLabelById(id);
    }

    @Override
    @Transactional
    public String updateOrSave(Article article) {
        // 1.id不为空，更新操作
        if (StringUtils.isNotEmpty(article.getId())) {
            // 更新：先删除文章知识点中间表数据，再新增到中间表
            baseMapper.deleteArticleLabel(article.getId());
            // 设置更新时间
            article.setUpdateDate(new Date());
        }

        // 如果文章是不公开的，直接审核通过，否则待审核
        if (article.getIspublic() == 0) {
            article.setStatus(ArticleStatusEnum.SUCCESS.getCode());
        } else {
            article.setStatus(ArticleStatusEnum.WAIT.getCode());
        }

        // 2.更新或保存文章信息表
        super.saveOrUpdate(article);

        // 3.新增到文章知识点中间表
        if (CollectionUtils.isNotEmpty(article.getLabelIds())) {
            baseMapper.saveArticleLabel(article.getId(), article.getLabelIds());
        }
        return article.getId();
    }

    @Override
    public void updateStatus(String id, ArticleStatusEnum statusEnum) {
        Article article = baseMapper.selectById(id);
        article.setStatus(statusEnum.getCode());
        baseMapper.updateById(article);
    }

    @Override
    public IPage<Article> findListByUserId(ArticleUserREQ req) {
        if (StringUtils.isBlank(req.getUserId())) {
            return null;
        }
        QueryWrapper<Article> wrapper = new QueryWrapper<Article>();
        wrapper.eq("user_id", req.getUserId());

        if (req.getIsPublic() != null) {
            wrapper.eq("ispublic", req.getIsPublic());
        }

        // 排序
        wrapper.orderByDesc("update_date");
        return baseMapper.selectPage(req.getPage(), wrapper);
    }

    @Override
    public Result updateThumhup(String id, int count) {
        if (count != -1 && count != 1) {
            return Result.error("无效操作");
        }
        if (StringUtils.isBlank(id)) {
            return Result.error("无效操作");
        }
        Article article = baseMapper.selectById(id);
        if (article == null) {
            return Result.error("文章不存在");
        }
        if (article.getThumhup() <= 0 && count == -1) {
            return Result.error("无效操作");
        }
        article.setThumhup(article.getThumhup() + count);
        // 不用设置更新时间，更新时间是编辑后才设置
        baseMapper.updateById(article);
        return Result.ok();
    }

    @Override
    public Result updateViewCount(String id) {
        if (StringUtils.isBlank(id)) {
            return Result.error("无效操作");
        }
        Article article = baseMapper.selectById(id);
        if (article == null) {
            return Result.error("文章不存在");
        }
        article.setViewCount(article.getViewCount() + 1);
        // 不用设置更新时间，更新时间是编辑后才设置
        baseMapper.updateById(article);
        return Result.ok();
    }

    @Override
    public IPage<Article> findListByLabelIdOrCategoryId(ArticleListREQ req) {
        return baseMapper.findListByLabelIdOrCategoryId(req.getPage(), req);
    }

    @Override
    public Integer getArticleTotal() {
        // 查询总文章数
        QueryWrapper<Article> wrapper = new QueryWrapper<>();
        // 状态是审核通过
        wrapper.eq("status", ArticleStatusEnum.SUCCESS.getCode());
        // 公开
        wrapper.eq("ispublic", 1);
        return baseMapper.selectCount(wrapper);
    }

    @Override
    public Map<String, Object> selectCategoryTotal() {
        List<Map<String, Object>> maps = baseMapper.selectCategoryTotal();

        // 将分类名称提取到集合中,
        List<Object> nameList = new ArrayList<>();
        for (Map<String, Object> map : maps) {
            nameList.add(map.get("name"));
        }

        // 封装响应数据
        Map<String, Object> data = new HashMap<>();
        data.put("nameAndValueList", maps);
        data.put("nameList", nameList);
        return data;
    }

    @Override
    public Map<String, Object> selectMonthArticleTotal() {
        List<Map<String, Object>> maps = baseMapper.selectMonthAritcleTotal();
        // 将年月提取到集合中
        List<Object> yearMonthList = new ArrayList<>();
        // 将每个月的文章数提取集合中
        List<Object> aritcleTotalList = new ArrayList<>();
        for (Map<String, Object> map : maps) {
            yearMonthList.add(map.get("year_month"));
            aritcleTotalList.add(map.get("total"));
        }
        // 封装响应数据
        Map<String, Object> data = new HashMap<>();
        data.put("yearMonthList", yearMonthList);
        data.put("aritcleTotalList", aritcleTotalList);
        return data;
    }

    @Override
    public boolean updateUserInfo(UserInfoREQ req) {
        return baseMapper.updateUserInfo(req);
    }


    @Override
    public Integer searchCountDayNum() {
        return baseMapper.searchCountDayNum();
    }

    @Override
    public Integer searchNumberOfArticlesInYesterdaySDay() {
        return baseMapper.searchNumberOfArticlesInYesterdaySDay();
    }

    @Override
    public Integer searchNumberOfArticlesInWeek() {
        return  baseMapper.searchNumberOfArticlesInWeek();
    }

}
